package com.yuanfeng.commoms.aspect;

import com.alibaba.fastjson.JSON;
import com.yuanfeng.commoms.annnotation.SysLog;
import com.yuanfeng.commoms.rocketmq.MqSendUtils;
import com.yuanfeng.commoms.util.Constant;
import com.yuanfeng.commoms.util.IpUtils;
import com.yuanfeng.commoms.vo.user.SysLogVO;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
public class SysLogAspect {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Pointcut("@annotation(com.yuanfeng.commoms.annnotation.SysLog)")
    public void logPointCut() {

    }

    @AfterReturning("logPointCut()")
    public void saveSysLog(JoinPoint joinPoint) {

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();//获取request
        try {
            //保存日志
            SysLogVO sysLog = new SysLogVO();

            //从切面织入点处通过反射机制获取织入点处的方法
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            //获取切入点所在的方法
            Method method = signature.getMethod();
            //获取操作
            SysLog myLog = method.getAnnotation(SysLog.class);
            if (null != myLog) {
                String value = myLog.value();
                sysLog.setOperation(value);//保存获取的操作
            } else {
                sysLog.setOperation("");//保存获取的操作
            }
            //获取请求的类名
            String className = joinPoint.getTarget().getClass().getName();
            //获取请求的方法名
            String methodName = method.getName();
            sysLog.setMethod(className + "." + methodName);

            //请求的参数
            Object[] args = joinPoint.getArgs();
            //将参数所在的数组转换成Map,此处只转换第一个参数
//            Map paraMap = objectMapper.convertValue(args[0], Map.class);
            JsonRequestWrapper jsonRequestWrapper = new JsonRequestWrapper(request);
            String body = jsonRequestWrapper.getBody();
            System.out.println("body" + body);//获取请求的参数
            Map paraMap = JSON.parseObject(body, Map.class);
            sysLog.setLogParam(StringUtils.isBlank(body) ?null:paraMap.toString());
            sysLog.setCreateTime(Date.from(LocalDateTime.now().atZone( ZoneId.systemDefault()).toInstant()));
            //获取用户名
            if(StringUtils.isNotBlank(body)){
                UserPermissionsResult userPermissionsResult = UserService
                        .judgePermissions(Constant.SERLLER_SHOP_SETSHOP, (String) paraMap.get("token"));
                if( null != userPermissionsResult.getUserId()  &&  null !=  userPermissionsResult.getUserName()){
                    sysLog.setUsername(userPermissionsResult.getUserName());
                    sysLog.setUserid(userPermissionsResult.getUserId());
                }
            } else{
                sysLog.setUsername("0");
                sysLog.setUserid("0");
            }

            //获取用户ip地址
            sysLog.setLogIp(IpUtils.getIpAddress());


            //调用service保存SysLog实体类到数据库
            log.info(sysLog.toString());
            Map<String, Object> map=new HashMap<>();
            map.put("log",sysLog);
            //发送操作日志消息
            MqSendUtils.mqSendSysLog(map);

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 获取请求ip 本地可以获取 但是部署服务器后  因为nginx的反向代理 获取的是nginx 的ip
     * @param request
     * @return
     * @throws Exception
     */
    public  String getIp(HttpServletRequest request) {
        String ip = null;
        try {
            ip = request.getHeader("X-Forwarded-For");
            if (ip != null){
                if (!ip.isEmpty() && !"unKnown".equalsIgnoreCase(ip)) {
                    int index = ip.indexOf(",");
                    if (index != -1) {
                        return ip.substring(0, index);
                    } else {
                        return ip;
                    }
                }
            }
            ip = request.getHeader("X-Real-IP");
            if (ip != null) {
                if (!ip.isEmpty() && !"unKnown".equalsIgnoreCase(ip)) {
                    return ip;
                }
            }
            ip = request.getHeader("Proxy-Client-IP");
            if (ip != null) {
                if (!ip.isEmpty() && !"unKnown".equalsIgnoreCase(ip)) {
                    return ip;
                }
            }
            ip = request.getHeader("WL-Proxy-Client-IP");
            if (ip != null) {
                if (!ip.isEmpty() && !"unKnown".equalsIgnoreCase(ip)) {
                    return ip;
                }
            }
            ip =  request.getRemoteAddr();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }
}

